home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
MOTOROLA
/
6805V107
/
68705.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-05-04
|
41KB
|
1,168 lines
program MC68705_Series_Software_Development;
{ M C 6 8 7 0 5 - S e r i e s S o f t w a r e D e v e l o p m e n t
S y s t e m
Author: D. R. Brooks
April 1989
Acknowledgements:
The functions ENVIRONMENT and SUBPROCESS are adapted from code published
by Borland International (publishers of Turbo Pascal), and in the public
domain.
The arithmetic-expression parser (in file 68705ASM.PAS) is based on the
recursive-descent parser published in "Advanced Turbo-Pascal Programming
and Techniques", by Schildt (McGraw Hill).
Revision History: Files Affected
1.01 Initial version All
1.02 Fix Emulator bugs (ROL, ROR) 68705DBG.PAS
1.03 Display count of instruction-execution cycles 68705DBG.PAS
1.04 Add Hex/Binary option to Load/Save file commands 68705 .PAS
1.05 Separate code pointers for Data & Code areas 68705ASM.PAS,
Added Logical operators (AND, OR, XOR) to exprns. 68705OPC.PAS,
Fixed bug in Exponentiation function 68705 .PAS
Added Conditional Assembly (IF, IFNOT, ENDIF, LISCN, NOLCN)
Added error-listing to screen, when main listing to disk
Corrected Include-file depth display, consistent w. listing
1.06 Corrected listing to show mem-bank for addresses > $1000 68705 .PAS,
Assembler initialises mem. to 0, not FF 68705ASM.PAS,
Assembler names accept '%', '@', 'A'..'Z', '_' 68705DBG.PAS
Amend listing to include execution cycles
Variable Stack bounds for different machines
1.07 Re-compiled for publication as Free Software 68705 .PAS
***************************************************************************
Compiler: Borland Turbo-Pascal, Revision 3.00
Compile to a .COM file, allowing this program use of about 2000
paragraphs free-store (to leave room for a word processor)
***************************************************************************}
{$C-} {$U-} {Disable ^C and ^S - program will handle them}
type
Str255 = String[255];
filename = string[38];
filextn = string[3];
symbol = string[8];
Regs = record Case Integer of
1: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags :integer);
2: (AL, AH, BL, BH, CL, CH, DL, DH :byte);
End;
memblk = record {Binary I/O file format}
mempage : array [0..255] of byte;
end;
oprec = record {Machine Opcode Table}
mnemonic : symbol; {Op-code mnemonic}
stub, {Basic hex. opcode if +ve, or command if -ve}
modes : integer; {Addressing modes, bit-mapped}
end;
oplist = array[1..127] of oprec; {Table of opcodes}
ViewControl = (Initz, View, Finish); {Mode controls for Viewer}
const
digit : set of char = ['0'..'9'];
logline : integer = 16; {Report line for subtasks}
filstem = ' Default File: '; {Flag work-file on screen}
srcextn : filextn = 'SRC'; {Std. extension for Source files}
lstextn : filextn = 'LST'; {Std. extension for Listing files}
hexextn : filextn = 'HEX'; {Std. extension for Hex. files}
binextn : filextn = 'BIN'; {Std. extension for Binary files}
comenv = 'COMSPEC'; {Environment key - DOS Command}
wprenv = 'WORDPATH'; {Environment key - Word Processor}
Nofile : string[6] = '<None>'; {Null-file name}
version : string[4] = '1.07'; {Program Version no.}
whitespace : set of char = [' ' , #9];
upper : set of char = ['A'..'Z'];
lower : set of char = ['a'..'z'];
symchar : set of char = ['%','@'..'Z','_']; {Legal assembler names}
TAB : char = ^I;
CR : char = ^M;
LF : char = ^J;
ESC : char = #27;
ENDFILE : char = ^Z;
{$I 68705OPC.PAS} {Local to Assembler, but nested Includes illegal}
{Descriptors shared by Assembler & Debugger}
type
AdrMode = (BTB, BSC, REL, IMM, DIR, EXT, INHA, INHX, IX2, IX1, IX);
ExClass = (BitTest, BitSetClr, BranchRel, RdModWrt, Control, RegMem);
ExRec = record {Instruction Decoding Record}
admode : AdrMode; {Addressing Mode}
opclass : ExClass; {Operation Class}
cycles : array[0..15] of byte; {Machine cycles - 0 =illegal}
bytes : byte; {Length of Instruction}
end;
ExList= array [0..15] of ExRec;
const
ExTable : ExList = (
{0} (admode: BTB; opclass: BitTest;
cycles: (5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5); bytes: 3),
{1} (admode: BSC; opclass: BitSetClr;
cycles: (5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5); bytes: 2),
{2} (admode: REL; opclass: Branchrel;
cycles: (3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3); bytes: 2),
{3} (admode: DIR; opclass: RdModWrt;
cycles: (5,0,0, 5,5,0,5,5,5,5,5,0,5,4,0,5); bytes: 2),
{4} (admode: INHA; opclass: RdModWrt;
cycles: (3,0,0, 3,3,0,3,3,3,3,3,0,3,3,0,3); bytes: 1),
{5} (admode: INHX; opclass: RdModWrt;
cycles: (3,0,0, 3,3,0,3,3,3,3,3,0,3,3,0,3); bytes: 1),
{6} (admode: IX1; opclass: RdModWrt;
cycles: (6,0,0, 6,6,0,6,6,6,6,6,0,6,5,0,6); bytes: 2),
{7} (admode: IX; opclass: RdModWrt;
cycles: (5,0,0, 5,5,0,5,5,5,5,5,0,5,4,0,5); bytes: 1),
{8} (admode: INHA; opclass: Control;
cycles: (9,6,0,10,0,0,0,0,0,0,0,0,0,0,2,2); bytes: 1),
{9} (admode: INHA; opclass: Control;
cycles: (0,0,0, 0,0,0,0,2,2,2,2,2,2,2,0,2); bytes: 1),
{A} (admode: IMM; opclass: RegMem;
cycles: (2,2,2, 2,2,2,2,0,2,2,2,2,0,6,2,0); bytes: 2),
{B} (admode: DIR; opclass: RegMem;
cycles: (3,3,3, 3,3,3,3,4,3,3,3,3,2,5,3,4); bytes: 2),
{C} (admode: EXT; opclass: RegMem;
cycles: (4,4,4, 4,4,4,4,5,4,4,4,4,3,6,4,5); bytes: 3),
{D} (admode: IX2; opclass: RegMem;
cycles: (5,5,5, 5,5,5,5,6,5,5,5,5,4,7,5,6); bytes: 3),
{E} (admode: IX1; opclass: RegMem;
cycles: (4,4,4, 4,4,4,4,5,4,4,4,4,3,6,4,5); bytes: 2),
{F} (admode: IX; opclass: RegMem;
cycles: (3,3,3, 3,3,3,3,4,3,3,3,3,2,5,3,4); bytes: 1)
) ;
var
commandpath, {Path to DOS COMMAND processor}
wordprocpath, {Path to Word Processor, or null}
dfltname, {Main Default file name}
listname, {Assembler listing file}
srcname : filename; {and Primary source-file}
hexfile, {Hex. (Motorola) format File}
lstfile : text; {Listing File}
binfile : file of memblk;{Binary image file}
memvalid, {Memory image holds a good program}
holdup, {Delay re-display screen}
altered : boolean; {Memory image changed: needs saving}
today : symbol; {Current date, ex-DOS}
memmax, {Highest memory address, for CPU}
oldsel, {Last sub-task run}
runjob, {Choose sub-task to run}
errcount : integer; {Count Assembler errors seen}
memory : array[0..8191] of byte; {The MC68705 RAM & EPROM}
prefix : string[80]; {Message frame - Asm. & Emulator}
StackBottom,
StackTop : integer; {Span of stack for current m/c}
{*************** Hexadecimal Output (Listing) Routines *****************
These all load results into PREFIX }
Procedure hexchar (loc :integer; value :byte); {List 1 hex. character}
const
hextab : array[0..15] of char =
('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
begin
prefix[loc]:= hextab[value and 15];
end;
Procedure hexbyte (loc :integer; value :byte); {List 1 hex. byte}
begin
hexchar(loc, value div 16);
hexchar(loc+1, value);
end;
Procedure hexword (loc, value :integer); {List 1 hex. word}
begin
hexbyte(loc ,hi(value));
hexbyte(loc+2,lo(value));
end;
Function hex( a:char) :integer; {Just the hex. value of 'a'}
begin
if a in digit then
hex:= ord(a) - ord('0')
else if a in ['A'..'F'] then
hex:= ord(a) - ord('A') + 10
else
hex:= -1;
end;
Function date : symbol; {Gets Date, as DD:MM:YY}
var
registers :Regs; {Machine registers for DOS call}
day, month :string[2];
year :string[4];
begin
with registers do begin
AX := $2A00; {DOS call for Date}
INTR ($21, registers); {To DOS}
str(CX:4,year); {Unpack Year}
str(lo(DX):2,day);
str(hi(DX):2,month); {Day & Month}
if (month[1] =' ') then month[1]:= '0'; {Leading zero in Month}
date:= day + ':' + month + ':' + copy(year,3,2);
end
end;
{************************** Main Program Routines ************************}
Procedure fixsystem(group :char); {Set up hardware configuration}
begin
case group of
'1': begin {MC1468705P3}
memmax:= 2047;
StackBottom:= 64;
StackTop:= 127;
end;
'2': begin {MC68705G2}
memmax:= 8191;
StackBottom:= 64;
StackTop:= 127;
end;
'3': begin {MC68HC705C8}
memmax:= 8191;
StackBottom:= 192;
StackTop:= 255;
end
end
end;
type
axis = (xco,yco);
coord = array[xco..yco] of integer;
const
horline : byte = $cd; {Special screen chars. - effects}
verline : byte = $ba;
topleft : byte = $c9;
topright : byte = $bb;
botleft : byte = $c8;
botright : byte = $bc;
midleft : byte = $cc;
midright : byte = $b9;
midtop : byte = $cb;
midbot : byte = $ca;
crossing : byte = $ce;
win1top : coord = (2,4); {Main screen windows}
win1bot : coord = (27,25);
win2top : coord = (37,4);
win2bot : coord = (80,22);
win3top : coord = (37,22);
win3bot : coord = (80,24);
cline : integer = 9; {No. of elements in "selector" array}
procedure choose(sel :integer); {Display one choice}
type
choice = string[20];
const
selector : array[1..9] of choice =(
'Select Default File',
'Memory Size',
'Run DOS Command',
'Run Word Processor',
'Assembler',
'Execution Emulator',
'Load Hex./Bin. file',
'Save Hex./Bin. file',
'Exit to DOS' );
begin
gotoxy(win1top[xco]+1,(2*sel)+win1top[yco]+1);
write(sel:2, '. ', selector[sel]);
end;
Function environment (arg :filename) : filename; {Get Environment String}
Type {Adapted from Borland}
Env=Array [0..32767] Of Char;
Var
EPtr: ^Env;
EStr: string[255];
Done: Boolean;
I: Integer;
Begin
for i:= 1 to length(arg) do arg[i]:= upcase(arg[i]); {Uppercase argt.}
EPtr:=Ptr(MemW[CSeg:$002C],0);
environment:= '';
I:=0;
Done:=False;
EStr:='';
Repeat
If EPtr^[I]=#0 Then
Begin
If EPtr^[I+1]=#0 Then Done:=True;
If Copy(EStr,1,length(arg)+1) = (arg + '=') then
Begin
environment:= copy(estr,length(arg)+2,100);
Done:=True;
End;
EStr:='';
End
Else EStr:=EStr+EPtr^[I];
I:=I+1;
Until Done;
End;
procedure showfile; {Display current file}
var
xpt, scol : integer;
begin
scol:= win3top[xco]+length(filstem)+1;
highvideo;
gotoxy(scol, win3top[yco]+1);
for xpt:= scol to win3bot[xco]-1 do write(' '); {Selective blank-out}
gotoxy(scol, win3top[yco]+1);
write(dfltname);
end;
procedure setwin(topgap :integer); {Set a reduced-size window}
begin
window ( win2top[xco]+1, win2top[yco]+topgap+1,
win2bot[xco]-1, win2bot[yco]-1);
end;
procedure showsel(level :integer); {Display Main-Menu choices}
var
ctr : integer;
begin
window(1,1,80,25); {Window controls OFF}
if (level = 0) then begin {Zero: re-display everything}
lowvideo;
for ctr:= 1 to cline do choose(ctr); {Main menu choices}
end
else if (level > 0) then begin {Positive: One in highlight}
highvideo;
choose(level);
end
else begin {Negative: One in background}
lowvideo;
choose(-level);
end;
window(win2top[xco]+1, win2top[yco]+1, {Then reset working window}
win2bot[xco]-1, win2bot[yco]-1);
end;
procedure vbar(start, finish :coord); {Draws a vertical bar on screen}
var {OMITTING the given end-points}
y : integer;
begin
for y:= start[yco]+1 to finish[yco]-1 do begin
gotoxy(start[xco], y);
write(chr(verline));
end
end;
procedure hbar(start, finish :coord); {Draws horizontal bar on screen}
var {OMITTING the given end-points}
x : integer;
begin
gotoxy(start[xco]+1, start[yco]);
for x:= start[xco]+1 to finish[xco]-1 do write(chr(horline));
end;
procedure drawwindow(tlt, brt :coord); {Draws rectangular box on screen}
var
x : integer;
diagl, diagr : coord;
waste : char;
begin {Find the diagonal points}
diagl:= tlt; diagl[yco]:= brt[yco];
diagr:= brt; diagr[yco]:= tlt[yco];
{Do the corners}
gotoxy(tlt[xco], tlt[yco]); write(chr(topleft));
gotoxy(diagl[xco], diagl[yco]); write(chr(botleft));
gotoxy(diagr[xco], diagr[yco]); write(chr(topright));
gotoxy(brt[xco], brt[yco]); write(chr(botright));
hbar(tlt,diagr); {Two horizontal bars}
hbar(diagl,brt);
vbar(tlt,diagl); {Two vertical bars}
vbar(diagr,brt);
end;
procedure SaveExorciser; forward; {Called here, before mem. changes}
function mainmenu(anew :boolean) :integer; {Main Menu, & get Choice}
var {"anew" causes complete re-draw}
savit : char;
switch, {Users choice}
ctr : integer;
dummy : Str255; {Waste input area}
const
title1 = 'Freeware by David R Brooks'; {Copyright Notice}
title2 = 'MC1468705 Series Software Development System';
willchange : set of byte = [5,7,9]; {Choices will change Memory}
function selection :integer; {Get users selection - main menu}
var
x : char;
begin
gotoxy(6,3); clreol;
write('CR to run Highlighted task');
gotoxy(2,2); clreol;
write('Choose from menu at Left [1-', cline:1, '] : ');
read(kbd,x);
if ((x = CR) and (oldsel > 0)) then x:= chr(oldsel+ord('0'));
write(x);
if (x in ['1'..'9']) then selection:= ord(x) - ord('0')
else selection:= 0;
prefix:= ''; {Cancel any log-line, after input}
end;
function yesno :char; {Test reply for Y or N}
var {on tasks which destroy Memory}
ans : char;
begin
gotoxy(2,2);
clreol;
write('Memory will be overwritten.');
gotoxy(2,3);
write(' Save Image File [Y/N] ?');
read(kbd,ans);
write(ans);
yesno:= upcase(ans);
end;
begin {M A I N M E N U D R A W N}
window(1,1,80,25); {Drop any existing window}
if (anew) then begin
clrscr; {Blank out screen}
highvideo;
gotoxy(5,1);
write(title1);
gotoxy(37,1);
write(title2);
lowvideo;
gotoxy(5,2);
for ctr:= 1 to length(title1) do write(chr(horline));
gotoxy(37,2);
for ctr:= 1 to length(title2) do write(chr(horline));
drawwindow(win1top,win1bot); {Two window frames}
drawwindow(win2top,win2bot);
drawwindow(win3top,win3bot); {Subsidiary window}
gotoxy(win3top[xco], win3top[yco]);
write(chr(midleft));
gotoxy(win3bot[xco], win3top[yco]);
write(chr(midright));
gotoxy(win3top[xco]+1, win3top[yco]+1);
write(filstem);
gotoxy(win1top[xco]+5, win1top[yco]+1);
write('M A I N M E N U');
holdup:= false;
end;
showfile; {Show default filename}
showsel(0); {Display all choices}
if (oldsel >0) then showsel(oldsel); {Indicate previous choice, if any}
if not holdup then clrscr;
highvideo;
gotoxy(2,17);
clreol;
write(prefix); {Any log returned by Sub-Task}
if holdup then begin
write(': Hit CR'); {Prompt}
readln(dummy); {Hold screen if reqd.}
clrscr; {Then wipe it}
gotoxy(2,17);
write(prefix); {Put back the report}
end;
holdup:= false;
switch:= selection;
while ((1 > switch) or (cline < switch)) do begin
highvideo; {Get selection}
gotoxy(2,4);
write('A digit, "1" to "', cline:1, '" please');
switch:= selection;
end;
clrscr;
if (oldsel >0) then showsel(-oldsel); {Drop old choice}
showsel(switch); {New choice}
oldsel:= switch;
if (memvalid and altered
and (lo(switch) in willchange)) then begin {Warning...}
savit:= yesno;
while (not (savit in ['Y', 'N'])) do begin
highvideo;
gotoxy(2,4);
write('"Y" or "N", please');
savit:= yesno;
end;
if (savit = 'Y') then begin
SaveExorciser; {Save memory image}
altered:= false;
end
end;
mainmenu:= switch; {Pass back selection}
end;
{$I 68705ASM.PAS} {Assembler-Module code}
{$I 68705SVC.PAS} {Services, common to Viewer & Emul.}
{$I 68705VIW.PAS} {File Viewer Module code}
{$I 68705DBG.PAS} {Instruction-Emulator code}
{**************************************************************************
S U B - T A S K P R O C E D U R E S
***************************************************************************}
function stdfile(extn :filextn) :filename; {Standard file extn.}
var
x : integer;
tmp : filename;
begin
tmp:= dfltname;
x:= pos('.',dfltname);
if (((extn <> srcextn) or (x = 0)) and (tmp <> '')) then begin
if (x > 0) then tmp:= copy(dfltname,1,x-1);
tmp:= tmp + '.' + extn;
end;
stdfile:= tmp;
end;
function workfile ( line :integer; {Line to put query on}
usage :filename; {Prompt string}
extn :filextn; {Default name extension}
nullok :boolean) {NUL message displayed}
:filename; {Makes correct file name}
var
work : filename;
wcol : integer;
begin
gotoxy(2,line);
lowvideo;
write(usage:8, ' name: [');
wcol:= wherex;
highvideo;
write(stdfile(extn));
lowvideo;
writeln(']');
if nullok then begin
gotoxy(3,line+1);
write('"NUL" =None');
end;
gotoxy(wcol-1,line+1);
write('>');
highvideo;
readln(work);
if (work = '') then work:= stdfile(extn);
if ((work = 'con') or (work = 'CON')) then work:= 'CON:';
if ((pos('.', work) =0) and
(work[length(work)] <> ':')) then work:= work + '.' + extn;
if ((copy(work,1,4) = 'NUL.') or
(copy(work,1,4) = 'nul.')) then work:= Nofile;
gotoxy(wcol,line+1);
write(work);
workfile:= work;
end;
Function SubProcess(CommandLine: Str255): Integer;
{Run a DOS Sub-Process}
Const {Borland Public-Domain}
SSSave: Integer=0;
SPSave: Integer=0;
Var
Registers : Regs;
FCB1,FCB2: Array [0..36] Of Byte;
PathName: filename;
CommandTail: Str255;
ParmTable: Record
EnvSeg: Integer;
ComLin: ^Integer;
FCB1Pr: ^Integer;
FCB2Pr: ^Integer;
End;
I,RegsFlags: Integer;
Begin
If Pos(' ',CommandLine)=0 Then
Begin
PathName:=CommandLine+#0;
CommandTail:=CR;
End
Else
Begin
PathName:=Copy(CommandLine,1,Pos(' ',CommandLine)-1)+#0;
CommandTail:=Copy(CommandLine,Pos(' ',CommandLine),255)+CR;
End;
CommandTail[0]:=Pred(CommandTail[0]);
With Registers Do
Begin
FillChar(FCB1,Sizeof(FCB1),0);
AX:=$2901;
DS:=Seg(CommandTail[1]);
SI:=Ofs(CommandTail[1]);
ES:=Seg(FCB1);
DI:=Ofs(FCB1);
MsDos(Registers); { Create FCB 1 }
FillChar(FCB2,Sizeof(FCB2),0);
AX:=$2901;
ES:=Seg(FCB2);
DI:=Ofs(FCB2);
MsDos(Registers); { Create FCB 2 }
ES:=CSeg;
BX:=SSeg-CSeg+MemW[CSeg:MemW[CSeg:$0101]+$112];
AH:=$4A;
MsDos(Registers); { Deallocate unused memory }
With ParmTable Do
Begin
EnvSeg:=MemW[CSeg:$002C];
ComLin:=Addr(CommandTail);
FCB1Pr:=Addr(FCB1);
FCB2Pr:=Addr(FCB2);
End;
InLine($8D/$96/ PathName /$42/ { <DX>:=Ofs(PathName[1]); }
$8D/$9E/ ParmTable / { <BX>:=Ofs(ParmTable); }
$B8/$00/$4B/ { <AX>:=$4B00; }
$1E/$55/ { Save <DS>, <BP> }
$16/$1F/ { <DS>:=Seg(PathName[1]); }
$16/$07/ { <ES>:=Seg(ParmTable); }
$2E/$8C/$16/ SSSave / { Save <SS> in SSSave }
$2E/$89/$26/ SPSave / { Save <SP> in SPSave }
$FA/ { Disable interrupts }
$CD/$21/ { Call MS-DOS }
$FA/ { Disable interrupts }
$2E/$8B/$26/ SPSave / { Restore <SP> }
$2E/$8E/$16/ SSSave / { Restore <SS> }
$FB/ { Enable interrupts }
$5D/$1F/ { Restore <BP>,<DS> }
$9C/$8F/$86/ RegsFlags / { Flags:=<CPU flags> }
$89/$86/ Registers ); { Registers.AX:=<AX>; }
If (RegsFlags And 1)<>0 Then SubProcess:=AX
Else SubProcess:=0;
End;
End;
procedure subprocessresult( res :integer); {Log result of Sub-Process call}
begin
case res of
0 : prefix:= ''; {Report result of DOS-call}
1 : prefix:= 'Invalid Function';
2 : prefix:= 'Bad command or file name';
7 : prefix:= 'Memory Control Block error';
8 : prefix:= 'Insufficient Memory';
10 : prefix:= 'Environment too Big';
11 : prefix:= 'Illegal .EXE Format';
end
end;
function openbin (reading :boolean) :boolean; {Try to open the BIN file}
var
binname : filename;
hold : boolean;
begin
binname:= workfile(6,'Bin-File',binextn,false);
assign(binfile,binname);
{$I-}
if reading then reset(binfile)
else rewrite(binfile);
{$I+}
hold:= (IOResult = 0);
if (not hold) then prefix:= 'Unable to open File';
openbin:= hold;
end;
function openhex (reading :boolean) :boolean; {Try to open the HEX file}
var
hexname : filename;
hold : boolean;
begin
hexname:= workfile(6,'Hex-File',hexextn,false);
assign(hexfile,hexname);
{$I-}
if reading then reset(hexfile)
else rewrite(hexfile);
{$I+}
hold:= (IOResult = 0);
if (not hold) then prefix:= 'Unable to open File';
openhex:= hold;
end;
function usehex :boolean; {Select HEX or BIN format}
var
ans : char;
const
valid : set of char = ['x', 'X', 'b', 'B'];
begin
ans:= ' ';
while not (ans in valid) do begin
gotoxy(2,2);
clreol;
lowvideo; write('Choose E');
highvideo; write('x');
lowvideo; write('orciser or ');
highvideo; write('B');
lowvideo; write('inary format: ');
read(kbd,ans);
gotoxy(2,4);
write('"B" or "X", please!');
end;
gotoxy(2,4); clreol;
gotoxy(2,2); clreol;
usehex:= (upcase(ans) = 'X');
end;
function accept(line :integer) :boolean; {User confirms task}
var
ans : char;
pos : integer;
begin
highvideo;
gotoxy(2,line);
write('OK to Proceed [Y/CR or N]: ');
pos:= wherex;
read(kbd,ans);
while (not (ans in ['Y', 'N', 'y', 'n', CR])) do begin
gotoxy(2, line+1);
write('"Y", CR, or "N", please');
gotoxy(pos, line);
read(kbd,ans);
end;
if (upcase(ans) in ['Y', 'y', CR]) then
accept:= true
else begin
accept:= false;
prefix:= 'Cancelled by User';
end
end;
{********************************************}
procedure SelectFile; {Choice 1: Change basic filename}
begin
gotoxy(2,8);
writeln('New Default file name?');
write(' >');
readln(dfltname);
end;
{********************************************}
procedure SetMemSize; {Choice 2: Select "EPROM" Size}
var
xp, yp : integer;
ans : char;
begin
setwin(0); {Set window}
clrscr;
lowvideo;
writeln;
writeln(' Select MCU Component:');
writeln;
writeln(' 1: 68705P3 - $7FF [2047]');
writeln(' 2: 68705G2 - $1FFF [8191]');
writeln(' 3: 68HC705C2 - $1FFF [8191]');
writeln;
highvideo;
writeln(' Current Size=', memmax:5);
writeln;
writeln;
write(' Choose [1, 2, 3] :');
xp:= wherex;
yp:= wherey;
read(kbd,ans);
write(ans);
while not (ans in ['1'..'3']) do begin
gotoxy(2,yp+2);
write(' "1", "2", or "3", Please');
gotoxy(xp,yp);
read(kbd,ans);
write(ans);
end;
fixsystem(ans);
if ans = '3' then memmax:= 8191
else memmax:= 2047;
str(memmax:5,prefix);
prefix:= 'Current Size=' + prefix;
end;
{********************************************}
procedure DOSCommand; {Choice 3: Run DOS command}
const
backstr = ' to return to 68705 System';
var
Command : Str255;
I : Integer;
dum : char;
begin
lowvideo;
gotoxy(2,8);
writeln('Enter DOS Command-Line:');
writeln(' [CR to run Command processor]');
write(' >');
highvideo;
readln(Command);
window(1,1,80,25); {Window off for DOS}
clrscr; {Clear out}
highvideo;
if (Command = '') then begin
writeln('Type EXIT', backstr);
I:= SubProcess(commandpath); {Run the full Command Shell}
end
else begin
I:= SubProcess(commandpath + ' /C ' + Command); {Run one Command}
writeln; {If quit by DOS-"EXIT", then no need to...}
highvideo; {Pause to let you read the DOS screen}
write('Hit any key', backstr);
read(kbd,dum);
end;
subprocessresult(I);
end;
{********************************************}
procedure WordProcessor; {Choice 4: Run Word Processor}
var
I : integer;
begin
if (wordprocpath = '') then
prefix:= 'Word-Proc. not attached: use DOS Cmnd.'
else begin
srcname:= workfile(6, 'Edit', srcextn,false);
if accept(10) then begin
window(1,1,80,25); {Reset the display}
clrscr;
highvideo;
I:= SubProcess(commandpath + ' /C ' +
wordprocpath + ' ' + srcname);
subprocessresult(I);
end
end
end;
{********************************************}
procedure DoAssembly; {Choice 5: Run the Assembler}
begin
srcname := workfile(6, 'Source', srcextn, false);
listname:= workfile(9, 'Listing', lstextn, true);
if accept(13) then begin
assign(lstfile, listname);
clrscr;
memvalid:= assemble; {Run the Assembler proper}
holdup:= not memvalid; {If error, pause screen}
end
end;
{********************************************}
procedure Emulator; {Choice 6: The instruction Emulator}
begin
if memvalid then begin
gotoxy(1,1); {Introductory HELP messages}
lowvideo;
writeln('You may choose a Documentation file to be');
writeln('displayed in a Window alongside your');
writeln('Emulation run. Commonly this would be the');
writeln('Assembly listing file.');
writeln('This file is called the Viewer File.');
listname:= workfile(8,'Viewer',lstextn,true);
if accept(11) then DoEmulation;
end
else
prefix:= 'No Valid Program in Memory';
end;
{********************************************}
procedure LoadExorciser; {Choice 7: Read a Motorola or Binary file}
procedure loadhexfile; {Option "X" - Motorola hex. format load}
var
linecount, {File record-count}
memaddr, {Memory load addr.}
coladd, {Source-line column}
bytecount : integer; {Count bytes in line}
temp, {Hold byte as read}
checksum : byte; {Hex. checksum}
fatal : integer; {Fatal file error}
function pickbyte : byte; {Get 1 hex. byte from file}
var
itmp1,
itmp2 : byte;
begin
itmp1:= hex(prefix[coladd]) and 255;
itmp2:= hex(prefix[coladd+1]) and 255;
if ((itmp1 or itmp2) > 16) then fatal:= 1 {Invalid hex.}
else itmp1:= (itmp1 shl 4) or itmp2;
coladd:= coladd+2;
checksum := checksum + itmp1;
bytecount:= bytecount -1;
pickbyte := itmp1;
end;
begin
if openhex(true) then begin {Open file...}
if accept(10) then begin
memvalid:= false;
for memaddr:= 0 to memmax do memory[memaddr]:= $ff;
fatal := 0;
linecount:= 0;
if (eof(hexfile)) then begin
prefix:= 'ZZ'; {Anything illegal}
fatal:= 4;
end
else begin
repeat
readln(hexfile,prefix); {Get a source line}
linecount:= linecount +1;
coladd := 3; {Column for first hex. data}
checksum := 0;
bytecount:= pickbyte; {Get byte count}
memaddr := (pickbyte shl 8);
memaddr := memaddr or pickbyte; {2-byte base addr.}
temp := pickbyte; {Yourdon loop for data}
while (bytecount > 0) do begin
if ((0 <= memaddr) and (memaddr < (memmax+1))) then
memory[memaddr]:= temp
else
fatal:= 2;
memaddr := memaddr +1;
temp := pickbyte;
end;
if (checksum <> $FF) then fatal:= 3;
until (eof(hexfile) or
(prefix[2] <> '1') or
(fatal >0));
end;
close(hexfile);
if ((prefix[2] ='9') and
(fatal =0)) then begin {Check it was the end record}
memvalid:= true; {Good program load}
str(linecount:4, prefix);
prefix:= prefix + ' Records Input';
end
else begin
str(linecount:5, prefix);
case fatal of
0: prefix:= 'No End Record at Line' + prefix;
1: prefix:= 'Invalid hex. char. in Line' + prefix;
2: prefix:= 'Address out of Range: Line' + prefix;
3: prefix:= 'Checksum Error in Line' + prefix;
4: prefix:= 'Premature end-of-file at Line' + prefix;
end
end
end
end
end; {of procedure loadhexfile}
procedure loadbinfile; {Choice "B" - binary format}
var
memaddr, {memory locn. to fill}
recount : integer; {count records read}
filbuff : memblk; {file buffer}
begin
if openbin(true) then begin
if accept(10) then begin
memvalid:= false; {Memory is trashed, until proved good}
for memaddr:= 0 to memmax do memory[memaddr]:= $ff;
memaddr:= 0; recount:= 0;
while (memaddr < memmax) and
(not eof(binfile)) do begin
read(binfile,filbuff);
recount:= recount+1;
move(filbuff,memory[memaddr],256); {fast block move}
memaddr:= memaddr+256;
end;
close(binfile);
memvalid:= true;
str(recount:5,prefix);
prefix:= prefix + ' Records Input';
end
end
end; {of procedure loadbinfile}
begin
if usehex then loadhexfile
else loadbinfile;
end; {of procedure LoadExorciser}
{********************************************}
procedure SaveExorciser; {Choice 8: Save Memory, in Hex./Bin. format}
procedure savehexfile; {Choice "X" - Motorola hex-format save}
{The routine breaks memory into 32-byte
blocks, and outputs any block not all-FF}
var
blockcount, {Count blocks written}
blockptr, {Point to start of current Block}
byteptr, {Point to current Byte}
bufptr, {Pointer into file buffer}
checksum : integer; {Binary sumcheck}
NZ : byte; {All-FF indicator}
begin
if memvalid then begin {Only run it if a good program stored}
blockcount:= 0;
prefix := 'S123'; {32 bytes per line, then reserve space}
for blockptr:= 1 to 7 do prefix:= prefix + ' ';
if openhex(false) then begin
if accept(10) then begin
blockptr:= 0; {Pascal can't do FOR...STEP}
while (blockptr < (memmax+1)) do begin {Check each block}
hexword(5,blockptr); {Memory address}
bufptr:= 9; {Start data field}
checksum:= 35 + lo(blockptr) + hi(blockptr);
NZ:= $FF;
for byteptr:= blockptr to (blockptr+31) do begin
hexbyte(bufptr,memory[byteptr]);
checksum:= checksum + memory[byteptr];
bufptr := bufptr +2;
NZ := NZ and memory[byteptr]; {The all-FF detector}
end;
if (NZ <> $FF) then begin
hexbyte(bufptr, ((not(checksum)) and $FF)); {Valid line - output}
writeln(hexfile,prefix);
blockcount:= blockcount +1;
end;
blockptr:= blockptr+32; {Next block}
end;
writeln(hexfile,'S9030000FC');
write(hexfile,ENDFILE); {DOS end-of-file mark}
close(hexfile);
str((blockcount+1):3,prefix);
prefix := prefix + ' Records Written'; {Log line}
altered:= false; {Memory safe, now}
end
end
else
prefix:= 'No valid program stored';
end
end; {of procedure savehexfile}
procedure savebinfile; {Choice "B" - binary format}
var
memaddr, {memory pointer}
recount : integer; {count records written}
filbuff : memblk; {file buffer}
begin
if memvalid then begin
if openbin(false) then begin
if accept(10) then begin
recount:= 0;
memaddr:= 0;
while memaddr < memmax do begin
move(memory[memaddr],filbuff,256);
write(binfile,filbuff);
recount:= recount+1;
memaddr:= memaddr+256;
end;
close(binfile);
str(recount:5,prefix);
prefix:= prefix + ' Records written';
end
end
end
end; {of procedure savebinfile}
begin
if usehex then savehexfile
else savebinfile;
end; {of procedure SaveExorciser}
{**************************************************************************
P R O G R A M M A I N L I N E
***************************************************************************}
begin
fixsystem('1'); {Default hardware configuration}
if (paramcount > 0) then dfltname:= paramstr(1)
else dfltname:= '';
oldsel := 1; {Default task: change name}
today := date; {Standard initialisation}
memvalid:= false; {Nothing in Memory, yet}
altered := false; {same}
prefix := 'Software Version No. ' + version; {Initial Display}
commandpath := environment(comenv);
wordprocpath:= environment(wprenv); {Get Environment pointers}
window(1,1,80,25);
if (wordprocpath = '') then begin
clrscr;
writeln('Enter pathname for Word Processor, or CR if none');
write(' >');
readln(wordprocpath); {Get path, if none}
end;
runjob:= mainmenu(true); {Initialise Menu, & choose}
while (runjob in [1..(cline-1)]) do begin
case runjob of {Run the reqd. sub-task}
1: SelectFile;
2: SetMemSize;
3: DOSCommand;
4: WordProcessor;
5: DoAssembly;
6: Emulator;
7: LoadExorciser;
8: SaveExorciser;
end;
altered:= runjob in [5,6,7]; {Memory has been changed}
runjob:= mainmenu(runjob in [3,4,6]); {Next choice}
end; {Choice ="cline" will exit}
window(1,1,80,25); {The end: window off}
clrscr;
end.